# coding:utf-8

import json
import random
import string
import time
from datetime import date

from flask import request, current_app
from flask_restful import Api, Resource

from app.token import AuthToken
from app.models import get_timestamp
from app.auth.constant import TO_RATE_CACHE_KEY
from app.op.models import User, Area, FrontendEventStat, UserTag, WxUser, Voucher
from app.op.constant import UserType, BusinessDisplay, AreaType
from app.msg.utils import generate_sms_content

from .views import Response
from .index_schemas import ip_in_schema, event_stat_schema
from .user_schemas import user_schema, user_mobile_schema
from .supplier_schemas import pack_schema, user_tag_schema, vouchers_schema
from .codes import SUCCESS, PARAMS_ILLEGAL
from .ip_utils import ip_util
from .utils import (
    generate_captcha, generate_demand_list_json, generate_to_demand
)
from app.wph_lib import alidayu
from app.msg.models import SMSLog
from app.auth.constant import CaptchaSmsChannel
from common.constant import Captcha_Sms_Channel_Key
from common.wechat_util import client

api = Api()


@api.resource('/cloud/health')
class QCloudHealthResource(Resource):
    """
    created by chenhj at 2018/8/30
    用于腾讯云负载均衡健康检查
    """
    def head(self):
        """
        created by chenhj at 2018/8/30

        """
        pass


@api.resource('/Ip/getIpInfo')
class IpResource(Resource):
    """
    created by chenhj at 2017/8/10

    """
    def post(self):
        """
        created by chenhj at 2017/8/10
        获取ip地址信息
        """
        data, errors = ip_in_schema.load(request.form)
        ip = request.remote_addr if not data else data['ip']
        ip_info = ip_util.find(ip)
        try:
            code = str(int(ip_info[2])) if ip_info.any() else '440304'
        except:
            code = '440304'

        prov = Area.get_by_args(id=code[:2] + '0000', type=AreaType.PROV.value)
        city = Area.get_by_args(id=code[:4] + '00', type=AreaType.CITY.value)
        county = Area.get_by_args(id=code, type=AreaType.COUNTY.value)

        if code.isdigit() and city and prov and county:
            ip_info = {
                'ip_info': {
                    'prov_id': prov.id,
                    'prov': prov.name,
                    'city_id': city.id,
                    'city': city.name,
                    'county_id': county.id,
                    'county': county.name
                }
            }
        else:
            ip_info = {
                'ip_info': {
                    'prov_id': '440000',
                    'prov': '广东省',
                    'city_id': '440300',
                    'city': '深圳市',
                    'county_id': '440304',
                    'county': '福田区'
                }
            }
        return Response(SUCCESS, ip_info)


@api.resource('/Index/getInitData')
class InitDataResource(Resource):
    """
    created by chenhj at 2017/8/10
    获取页面首页初始化信息
    """
    def post(self):
        """
        created by chenhj at 2017/8/11

        """
        token = request.cookies.get('opc_token')
        user = AuthToken.verify_auth_token(token)
        if user:
            ret = {
                'user': user_schema.dump(user)[0],
                'supplier_cnt': {
                    'prov_level': User.get_sup_count_by_cond(user.prov, user.level),
                    'prov': User.get_sup_count_by_cond(user.prov),
                    'total': User.get_all_sup_count(),
                    'wechat': WxUser.subscribe_count()
                },
                'pack': None,
                'partic_demand_list': [],
                'first_enter': 0,
                'available_vouchers': [],
                'unavailable_vouchers': [],
            }
            enterprise = user.enterprises.first()
            if enterprise and enterprise.valid:
                ret['user']['level'] = enterprise.level
                ret['user']['level_display'] = enterprise.level_display

            # 如果是今日首次登录, 则积分+1
            last_login_date = date.fromtimestamp(user.recent_login_at)
            today = date.today()
            if last_login_date < today:
                ret['first_enter'] = 1

            # 记录用户最近入站时间
            user.recent_login_at = get_timestamp()

            if user.type == UserType.ENGINEER.value:
                tag = UserTag.get_by_args(user_id=user.id)
                ret['user_tags'] = user_tag_schema.dump(tag)[0]
                ret['business_keys'] = BusinessDisplay
                ret['pack'] = pack_schema.dump(user.pack)[0]
                ret['partic_demand_list'] = generate_demand_list_json(
                    user.get_partic_demands()[:20], user
                )
                ret['my_demand_list'] = []
                ret['available_vouchers'] = vouchers_schema.dump(Voucher.available_vouchers(user.id))[0]
                ret['unavailable_vouchers'] = vouchers_schema.dump(Voucher.unavailable_vouchers(user.id))[0]
            else:
                ret['my_demand_list'] = generate_demand_list_json(user.demands, user)
                # 非工程商, 触发生成TO订单
                ip_info = ip_util.find(request.remote_addr)
                generate_to_demand(
                    current_app.redis.get(TO_RATE_CACHE_KEY) or 0, request.remote_addr, ip_info
                )
        else:
            ret = {
                'user': {
                    'type': 0,
                    'im_token': '',
                    'id': ''
                },
                'supplier_cnt': {
                    'prov_level': 0,
                    'prov': 0,
                    'total': 0
                },
                'my_demand_list': [],
                'pack': None,
                'partic_demand_list': [],
                'first_enter': 0,
                'available_vouchers': [],
                'unavailable_vouchers': [],
            }
            # 非工程商, 触发生成TO订单
            ip_info = ip_util.find(request.remote_addr)
            generate_to_demand(
                current_app.redis.get(TO_RATE_CACHE_KEY) or 0, request.remote_addr, ip_info
            )
        return Response(SUCCESS, ret)


@api.resource('/SmsCaptcha/sendSmsCaptcha')
class SmsResource(Resource):
    """
    created by chenhj at 2017/8/14
    发送验证码
    """
    def post(self):
        data, errors = user_mobile_schema.load(request.form)
        if errors:
            return Response(PARAMS_ILLEGAL.new_format_msg(list(errors.values())[0][0]))

        captcha_sms_channel = current_app.redis.get(Captcha_Sms_Channel_Key) \
            or CaptchaSmsChannel.MENG_WANG.value
        mobile = data['mobile']
        key = 'captcha_{}'.format(mobile)
        captcha = current_app.redis.get(key)
        if not captcha:
            if captcha_sms_channel == CaptchaSmsChannel.NA.value:
                captcha = '1234'
            else:
                captcha = generate_captcha()
            current_app.redis.set(key, captcha, ex=30 * 60)

        template_code = 'NA'
        if captcha_sms_channel == CaptchaSmsChannel.MENG_WANG.value:
            template_code = 'CAPTCHA'
            content = generate_sms_content(
                template_code=template_code,
                captcha=captcha
            )
            current_app.captcha_producer.send(
                json.dumps({
                    'mobile': mobile,
                    'content': content,
                })
            )
        elif captcha_sms_channel == CaptchaSmsChannel.ALI_DA_YU.value:
            # 使用阿里大于发送短信
            template_code = 'SMS_52355022'
            req = alidayu.api.AlibabaAliqinFcSmsNumSendRequest()
            req.set_app_info(
                alidayu.appinfo('23382326', 'd6932553edc60a55fdd84e6efb1bd262'))
            req.sms_type = 'normal'
            req.rec_num = mobile
            req.sms_template_code = template_code
            req.sms_free_sign_name = 'LED屏'
            req.sms_param = {'captcha': captcha}
            req.getResponse()

        SMSLog.create(
            mobile=mobile,
            template_code=template_code,
            content=captcha,
        )

        return Response(SUCCESS)


@api.resource('/Frontend/event/statistic')
class FrontendEventStatResource(Resource):
    """
    created by chenhj at 2017/8/23
    记录某个前端事件的执行次数
    """
    def post(self):
        data, errors = event_stat_schema.load(request.form)
        if errors:
            return Response(PARAMS_ILLEGAL.new_format_msg(list(errors.values())[0][0]))

        today = date.today()

        stat = FrontendEventStat.get_by_args(
            date=today, event=data['event']
        )
        if not stat:
            FrontendEventStat.create(event=data['event'])
        else:
            stat.count += 1
        return Response(SUCCESS)


@api.resource('/wechat/jssdk/sign')
class WechatJsSdkSignResource(Resource):
    """
    获取jssdk的签名和ticket等信息
    """
    def __create_nonce_str(self):
        return (
            ''.join(
                random.choice(string.ascii_letters + string.digits)
                for _ in range(15)
            )
        )

    def __create_timestamp(self):
        return int(time.time())

    def post(self):
        """
        return signature to client to use jssdk
        :return:
        """
        # referer
        url = request.referrer
        ticket = client.jsapi.get_jsapi_ticket()
        nonceStr = self.__create_nonce_str()
        timestamp = self.__create_timestamp()
        ret = dict(
            nonceStr=nonceStr,
            ticket=ticket,
            timestamp=timestamp,
            url=url
        )
        ret['signature'] = client.jsapi.get_jsapi_signature(nonceStr, ticket, timestamp, url)
        ret['appid'] = client.appid
        return Response(info_dict=ret)
